
//Copyright 1997-2009 Syrinx Development, Inc.
//This file is part of the Syrinx Web Application Framework (SWAF).
// == BEGIN LICENSE ==
//
// Licensed under the terms of any of the following licenses at your
// choice:
//
//  - GNU General Public License Version 3 or later (the "GPL")
//    http://www.gnu.org/licenses/gpl.html
//
//  - GNU Lesser General Public License Version 3 or later (the "LGPL")
//    http://www.gnu.org/licenses/lgpl.html
//
//  - Mozilla Public License Version 1.1 or later (the "MPL")
//    http://www.mozilla.org/MPL/MPL-1.1.html
//
// == END LICENSE ==
using System;
using System.Collections;
using System.Xml;

using Swaf;
using Swaf.BizObj;

using Swaf.Container;

namespace Swaf.BizRule
{
	/// <summary>
	/// Summary description for BizObjRules.
	/// </summary>
	public class BizObjRules : IBizObjRules, INameAddressSupport
	{
		protected IApplication m_app = Application.currentApp;
		protected INameAddressSupport m_docModel = null;
		protected IDictionary m_crossReferenceDefinitions = new Hashtable();

		protected IBizObj m_detailedBizObj = null;
		protected IBizObjList m_bizObjList = null;
		protected IBizObjDefinition m_bizObjType = null;

		protected string m_getBizObjListRule = null;
		protected object m_getBizObjListRuleParams = null;

		protected string m_getBizObjDetailRule = null;
		protected object m_getBizObjDetailRuleParams = null;

		protected string m_newBizObjRule = null;
		protected string m_updateBizObjListRule = null;
		protected string m_updateBizObjRule = null;
		protected string m_deleteBizObjRule = null;

		public BizObjRules(XmlElement initInfo)
		{
			m_app = Application.currentApp;
			m_docModel = null;


			m_getBizObjListRule = initInfo.GetAttribute("getBizObjListRule");
			if(m_getBizObjListRule.Length == 0)
				m_getBizObjListRule = null;
			m_getBizObjDetailRule = initInfo.GetAttribute("getBizObjDetailRule");
			if(m_getBizObjDetailRule.Length == 0)
				m_getBizObjDetailRule = null;
			foreach(XmlNode child in initInfo.ChildNodes)
			{
				if(child.Name.Equals("CrossReference"))
				{
					XmlElement crossRef = (XmlElement)child;
					m_crossReferenceDefinitions[crossRef.GetAttribute("dataRef")] = crossRef.GetAttribute("modelRef");
				}
			}

			setupCrossReferences();
		}

		public void defineDocumentContext(IApplication app, INameAddressSupport docModel)
		{
			m_app = app;
			m_docModel = docModel;
			setupCrossReferences();
		}

		public string GetBizObjListRule {get{return m_getBizObjListRule;}}

		public string GetDetailedBizObjRule {get{return m_getBizObjDetailRule;}}

		public string AddNewBizObjRule {get{return m_newBizObjRule;}}

		public string UpdateBizObjListRule {get{return m_updateBizObjListRule;}}

		public string UpdateBizObjRule {get{return m_updateBizObjRule;}}

		public string DeleteBizObjRule {get{return m_deleteBizObjRule;}}

		public object BizObjDetailRuleParams
		{
			get
			{
				return m_getBizObjDetailRuleParams;
			}
			set
			{
				m_getBizObjDetailRuleParams=value;
			}
		}
		public IBizObj BizObj
		{
			get
			{
				if(m_detailedBizObj != null)
					return m_detailedBizObj;
				else if(m_getBizObjDetailRule != null)
				{
					IResults rc = m_app.ruleMgr.execute(m_getBizObjDetailRule, m_getBizObjDetailRuleParams);
					if(rc.CallResults != null)
						return (IBizObj)rc.CallResults;
				}
				return null;
			}
		}

		public object BizObjListRuleParams
		{
			get
			{
				return m_getBizObjListRuleParams;
			}
			set
			{
				m_getBizObjListRuleParams=value;
			}
		}
		public IBizObjList BizObjList
		{
			get
			{
				if(m_bizObjList != null)
					return m_bizObjList;
				else if(m_getBizObjListRule != null)
				{
					IResults rc = null;
					if(m_getBizObjListRuleParams == null)
						rc = m_app.ruleMgr.execute(m_getBizObjListRule);
					else
						rc = m_app.ruleMgr.execute(m_getBizObjListRule, m_getBizObjListRuleParams);
					if(rc.CallResults != null)
						return (IBizObjList)rc.CallResults;
					if(rc.ExceptionInfo != null)
						m_app.Log.println(Application.DEFAULT_FRAMEWORK_LOG_LEVEL,"BizObjRules.BizObjList: Failure when calling business rule {0}. Cause:\r\n{1}", m_getBizObjListRule, rc.ExceptionInfo.ToString());
				}
				return null;
			}
		}

		public IBizObjDefinition BizObjType
		{
			get
			{
				return m_bizObjType;
			}
		}


		public void startGetBizObjList(object ruleParam, object callback, string callbackMethod)
		{
			// TODO:  Add BizObjRules.startGetBizObjList implementation
		}

		public void startGetBizObjList(object ruleParam)
		{
			// TODO:  Add BizObjRules.Swaf.BizRule.IBizObjRules.startGetBizObjList implementation
		}

		public void startGetDetailedBizObj(object ruleParam, object callback, string callbackMethod)
		{
			if(m_getBizObjDetailRule != null)
				m_app.ruleMgr.execute(m_getBizObjDetailRule, callback, callbackMethod, ruleParam);
			else
				throw new Exception("Cannot get detailed bizobj info when no rule for it has been specified.");
		}

		public void startGetDetailedBizObj(object ruleParam)
		{
			// TODO:  Add BizObjRules.Swaf.BizRule.IBizObjRules.startGetDetailedBizObj implementation
		}

		public void addBizObjListChangedListener(Swaf.BizRule.BizObjRuleDataAvailable listener)
		{
			// TODO:  Add BizObjRules.addBizObjListChangedListener implementation
		}

		public void addBizObjDeleteCompleteListener(Swaf.BizRule.BizObjRuleUpdateComplete listener)
		{
			// TODO:  Add BizObjRules.addBizObjDeleteCompleteListener implementation
		}

		public void addBizObjChangedListener(Swaf.BizRule.BizObjRuleDataAvailable listener)
		{
			// TODO:  Add BizObjRules.addBizObjChangedListener implementation
		}

		public void addBizObjUpdateCompleteListener(Swaf.BizRule.BizObjRuleUpdateComplete listener)
		{
			// TODO:  Add BizObjRules.addBizObjUpdateCompleteListener implementation
		}

		public void addBizObjAddNewCompleteListener(Swaf.BizRule.BizObjRuleUpdateComplete listener)
		{
			// TODO:  Add BizObjRules.addBizObjAddNewCompleteListener implementation
		}
		#region INameAddressSupport Members

		public bool containsField(string nameAddress)
		{
			string myName = NameAddress.getFirstAddress(nameAddress);
			return (String.Compare(myName, "bizobj", true) == 0 ||
				String.Compare(myName, "bizobjlist", true) == 0);

		}

		public bool isGetOnly
		{
			get
			{
				// TODO:  Add BizObjRules.isGetOnly getter implementation
				return false;
			}
		}

		public Swaf.Container.XmlSerializationSupport SerializationSupport
		{
			get
			{
				// TODO:  Add BizObjRules.SerializationSupport getter implementation
				return new Swaf.Container.XmlSerializationSupport ();
			}
		}

		public void put(string nameAddress, object val, object extraInfo)
		{
			put(nameAddress, val);
		}

		public void put(string nameAddress, object val)
		{
			string myName = NameAddress.getFirstAddress(nameAddress);
			if(String.Compare(myName, "bizobj",true) == 0)
				this.BizObj.put(NameAddress.getRemainingAddress(nameAddress), val);
			else
				throw new BaseException(String.Format("Unknown name '{0}'. Valid options are 'bizobj' and 'bizobjlist' only for this node", myName));
		}

		public string getXml(string options)
		{
			// TODO:  Add BizObjRules.getXml implementation
			return null;
		}

		public object get(string nameAddress, object oneArg)
		{
			return this.get(nameAddress, new object[]{oneArg});
		}

		public object get(string nameAddress)
		{
			return this.get(nameAddress, new object[]{});
		}

		public object get(string nameAddress, params object[] infoArgs)
		{
			if(nameAddress == null || nameAddress.Length == 0)
				return this;

			string myName = NameAddress.getFirstAddress(nameAddress);
			if(String.Compare(myName, "bizobj", true) == 0)
				return this.BizObj.get(NameAddress.getRemainingAddress(nameAddress), infoArgs);

			return null;
		}

		public string Xml
		{
			get
			{
				// TODO:  Add BizObjRules.Xml getter implementation
				return null;
			}
		}

		#endregion

		protected void setupCrossReferences()
		{
			foreach(DictionaryEntry entry in m_crossReferenceDefinitions)
			{
				string dataRef = (string)entry.Key;
				string modelRef = (string)entry.Value;
				string baseName = NameAddress.getFirstAddress(modelRef);

				INameAddressSupport baseModel = null;
				if(String.Compare(baseName, "doc", true) == 0)
					baseModel = m_docModel;
				else if(String.Compare(baseName, "session", true) == 0)
					baseModel = m_app.sessionData;
				else if(String.Compare(baseName, "application", true) == 0)
					baseModel = m_app.appData;

				if(baseModel == null)
					m_app.Log.println(Application.DEFAULT_FRAMEWORK_LOG_LEVEL,"BizObjRules.setupCrossReferences was unable to setup a cross reference for modelRef '{0}'", modelRef);
				else
				{
				}
			}
		}
		public IEnumerator GetEnumerator() { return null; }
	}
}
